package cn.li.security.sms;

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.Assert;


/**
 * 短信验证专用的Provier 用于对短信Token进行校验
 *  目的是为了授权，产生授权的实体Authentication
 */
@Slf4j
public class SmsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {


    @Setter
    private ISmsUserDetailService smsUserService;

    //验证短信验证码校验
    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        if (authentication.getCredentials() == null) {
            logger.debug("Authentication failed: no phoneVerifyCode provided");
            throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials","Bad credentials"));
        }
        String verifyCode = authentication.getCredentials().toString(); //取得验证码
        String phone = authentication.getPrincipal().toString(); //取得电话号码
        if (!smsUserService.testVerifyCode(phone , verifyCode)) {
            logger.debug("Authentication failed: verifyCode does not match stored value");
            throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials","Bad credentials"));
        }
    }


    //通过phone 获得 userDetail
    @Override
    protected UserDetails retrieveUser(String phone, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        return this.smsUserService.loadUserByPhone(phone);
    }

    protected void doAfterPropertiesSet() throws Exception {
        Assert.notNull(this.smsUserService, "A ISmsUserDetailService must be set");
    }

}